/* =================================================================================
File name:      PID_PMEASURE_H
    比例测量PID算法
===================================================================================*/

#ifndef _PID_PMEASURE_H_
#define _PID_PMEASURE_H_
#include <stdint.h>
#include <stdbool.h>
// Constants used in some of the functions below
/// 比例测量类型
typedef enum
{
    P_ON_M = 0,
    P_ON_E = 1

} pid_measure_type;
/// 控制输出类型
typedef enum
{
    AUTOMATIC = 1,
    MANUAL = 0

} pid_ctrl_model_type;
// 输出方向类型
typedef enum
{
    DIRECT = 0,
    REVERSE = 1

} pid_out_dir_type;

typedef struct pid_pmeasure_ctrl
{
    /* data */
    float dispKp; // * we'll hold on to the tuning parameters in user-entered
    float dispKi; //   format for display purposes
    float dispKd; //

    float kp; // * (P)roportional Tuning Parameter
    float ki; // * (I)ntegral Tuning Parameter
    float kd; // * (D)erivative Tuning Parameter

    pid_out_dir_type controllerDirection;
    pid_measure_type pOn;

    float *_input;    // * Pointers to the Input, Output, and Setpoint variables
    float *_output;   //   This creates a hard link between the variables and the
    float *_setpoint; //   PID, freeing the user from having to constantly tell us
                        //   what these values are.  with pointers we'll just know.

    unsigned long lastTime;
    float outputSum, lastInput;

    unsigned long SampleTime;
    float outMin, outMax;
    bool inAuto, pOnE;
} pid_pmeasure_ctrl_t;

pid_pmeasure_ctrl_t *pid_pmeasure_ctrl_new(float* input, float* output, float* setpoint,
        float kp, float ki, float kd, pid_measure_type pOn, pid_out_dir_type controllerDirection);

void pid_pmeasure_ctrl_delete(pid_pmeasure_ctrl_t *handle);

void pid_pmeasure_ctrl_set_model(pid_pmeasure_ctrl_t * handle, pid_ctrl_model_type model);
bool  pid_pmeasure_ctrl_compute(pid_pmeasure_ctrl_t * handle);
void pid_pmeasure_ctrl_set_output_limits(pid_pmeasure_ctrl_t *handle, float Min, float Max);
void pid_pmeasure_ctrl_set_tunings(pid_pmeasure_ctrl_t *handle, float Kp, float Ki, float Kd, pid_measure_type POn);
void pid_pmeasure_ctrl_set_controller_direction(pid_pmeasure_ctrl_t * handle,pid_out_dir_type dir);
void pid_pmeasure_ctrl_set_sampletime(pid_pmeasure_ctrl_t *handle, int NewSampleTime);
float pid_pmeasure_ctrl_get_kp(pid_pmeasure_ctrl_t * handle);
float pid_pmeasure_ctrl_get_ki(pid_pmeasure_ctrl_t * handle);
float pid_pmeasure_ctrl_get_kd(pid_pmeasure_ctrl_t * handle);

pid_ctrl_model_type pid_pmeasure_ctrl_get_model(pid_pmeasure_ctrl_t * handle);

pid_out_dir_type pid_pmeasure_ctrl_get_direction(pid_pmeasure_ctrl_t * handle);

#endif // __PID_H__